package com.learning.bio.client;

import com.learning.bio.server.Server;
import com.learning.bio.utils.BaseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ServerSocketFactory;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;

/**
 * @Author: wcl
 * @Description:
 * @Date: Create in 2:52 PM 2018/11/1
 * @Modified By:
 */
public class Client {

    private static final Logger LOGGER = LoggerFactory.getLogger(Client.class);

    private static final ExecutorService threadPool = BaseUtils.getThreadPool();

    private static final int DEFAULT_SERVER_PORT = 9999;

    private static final String DEFAULT_SERVER_HOST = "127.0.0.1";

    private Socket socket;

    private Object startLock = new Object();

    private Object closeLock = new Object();

    public static void main(String[] args) {
        List<Client> clients = new ArrayList<>();
        for (int i = 0; i < 3; i++ ) {
            threadPool.submit(() -> {
                Client client = new Client();
                try {
                    client.send();
                    clients.add(client);
                } catch (IOException e) {
                    LOGGER.error("客户端启动错误->{}", e.getMessage());
                }
            });
        }

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            LocalDateTime now = LocalDateTime.now();
            LOGGER.info("开始执行结束程序:{}", now);
            clients.forEach(client -> client.stop());
            threadPool.shutdownNow();

        }));
    }

    public void send() throws IOException {
        LOGGER.info("开启客户端。。。");
        send(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT);
    }

    public void send(String host, int port) throws IOException {
        synchronized (startLock) {

            socket = new Socket(host, port);
            String threadName = Thread.currentThread().getName();
            threadPool.submit(() -> {
                BufferedWriter out = null;
                try {
                    out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                    String content;
                    while (true) {
                        content =  "当前时间:" + LocalDateTime.now();
                        Thread.sleep(10000);
                        out.write(content);
                        out.newLine();
                        out.flush();
                    }
                } catch (IOException e) {

                } catch (InterruptedException e) {

                } finally {
                    LOGGER.info("这段代码会执行吗？");
                    BaseUtils.close(out, threadName + "输出流");
                }

            });

            threadPool.submit(() -> {
                BufferedReader is = null;
                try {
                    is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    String content;
                    while (true) {
                        if ((content = is.readLine()) != null) {
                            LOGGER.info("{}接收到的内容:{}", socket.getInetAddress() + ":" + socket.getLocalPort(), content);
                        }
                    }
                } catch (IOException e) {
                    LOGGER.error(e.getMessage());
                } finally {
                    BaseUtils.close(is, threadName + "输入流");
                }
            });
        }

    }

    public void stop() {
        synchronized (closeLock) {
            LOGGER.info("客户端准备关闭");
            BaseUtils.close(socket, "客户端");
            LOGGER.info("客户正常关闭:{}", socket);
        }
    }

}
